using System;
using System.Collections;
using System.Collections.Generic;
using Entitas;
using UnityEngine;

public class GetSameColorSystem : ReactiveSystem<GameEntity>
{
    private Contexts _contexts;

    public GetSameColorSystem(Contexts contexts) : base(contexts.game)
    {
        _contexts = contexts;
    }

    protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
    {
        return context.CreateCollector(GameMatcher.GetSameColor);
    }

    protected override bool Filter(GameEntity entity)
    {
        return entity.isGetSameColor;
    }

    protected override void Execute(List<GameEntity> entities)
    {
        foreach (var entity in entities)
        {
            entity.isGetSameColor = false;
        }
    }

    private void JudgeLeft(GameEntity entity)
    {
        CustomVector2 pos = entity.itemIndex.index;
        List<IEntity> sameColorItems = new List<IEntity>();

        for (int i = pos.x - 1; i >= 0; i--)
        {
            AddSameColorItem(entity, i, pos.y, sameColorItems);
        }
    }

    private void JudgeRight(GameEntity entity)
    {
        CustomVector2 pos = entity.itemIndex.index;
        List<IEntity> sameColorItems = new List<IEntity>();

        for (int i = pos.x + 1; i < _contexts.game.gameBoard.columns; i++)
        {
            AddSameColorItem(entity, i, pos.y, sameColorItems);
        }
    }

    private void JudgeUp(GameEntity entity)
    {
        CustomVector2 pos = entity.itemIndex.index;
        List<IEntity> sameColorItems = new List<IEntity>();

        for (int i = pos.y + 1; i < _contexts.game.gameBoard.rows; i++)
        {
            AddSameColorItem(entity, pos.x, i, sameColorItems);
        }
    }

    private void JudgeDown(GameEntity entity)
    {
        CustomVector2 pos = entity.itemIndex.index;
        List<IEntity> sameColorItems = new List<IEntity>();

        for (int i = pos.y - 1; i >= 0; i--)
        {
            AddSameColorItem(entity, pos.x, i, sameColorItems);
        }
    }

    private bool AddSameColorItem(GameEntity entity, int x, int y, List<IEntity> sameColorItems)
    {
        string colorName = entity.loadPrefab.path;
        if (JudgeSameColorItem(colorName, x, y).isSame)
        {
            sameColorItems.Add(JudgeSameColorItem(colorName, x, y).entity);
        }

        return JudgeSameColorItem(colorName, x, y).isSame;
    }

    private (bool isSame, GameEntity entity) JudgeSameColorItem(string colorName, int x, int y)
    {
        var entities = _contexts.game.GetEntitiesWithItemIndex(new CustomVector2(x, y));
        var entity = entities.SingleEntity();

        if (entities.Count == 1)
        {
            if (!entity.isMovable)
            {
                return (false, entity);
            }

            return (entity.loadPrefab.path == colorName, entity);
        }

        return (false, entity);
    }
}